{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Configurations for Colab"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import sys\n",
    "IN_COLAB = \"google.colab\" in sys.modules\n",
    "\n",
    "if IN_COLAB:\n",
    "    !apt install python-opengl\n",
    "    !apt install ffmpeg\n",
    "    !apt install xvfb\n",
    "    !pip install pyvirtualdisplay\n",
    "    !pip install gym[all]\n",
    "    from pyvirtualdisplay import Display\n",
    "    \n",
    "    # Start virtual display\n",
    "    dis = Display(visible=0, size=(400, 400))\n",
    "    dis.start()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 05. Noisy Networks for Exploration\n",
    "\n",
    "[M. Fortunato et al., \"Noisy Networks for Exploration.\" arXiv preprint arXiv:1706.10295, 2017.](https://arxiv.org/pdf/1706.10295.pdf)\n",
    "\n",
    "\n",
    "NoisyNet is an exploration method that learns perturbations of the network weights to drive exploration. The key insight is that a single change to the weight vector can induce a consistent, and potentially very complex, state-dependent change in policy over multiple time steps.\n",
    "\n",
    "Firstly, let's take a look into a linear layer of a neural network with $p$ inputs and $q$ outputs, represented by\n",
    "\n",
    "$$\n",
    "y = wx + b,\n",
    "$$\n",
    "\n",
    "where $x \\in \\mathbb{R}^p$ is the layer input, $w \\in \\mathbb{R}^{q \\times p}$, and $b \\in \\mathbb{R}$ the bias.\n",
    "\n",
    "The corresponding noisy linear layer is defined as:\n",
    "\n",
    "$$\n",
    "y = (\\mu^w + \\sigma^w \\odot \\epsilon^w) x + \\mu^b + \\sigma^b \\odot \\epsilon^b,\n",
    "$$\n",
    "\n",
    "where $\\mu^w + \\sigma^w \\odot \\epsilon^w$ and $\\mu^b + \\sigma^b \\odot \\epsilon^b$ replace $w$ and $b$ in the first linear layer equation. The parameters $\\mu^w \\in \\mathbb{R}^{q \\times p}, \\mu^b \\in \\mathbb{R}^q, \\sigma^w \\in \\mathbb{R}^{q \\times p}$ and $\\sigma^b \\in \\mathbb{R}^q$ are learnable, whereas $\\epsilon^w \\in \\mathbb{R}^{q \\times p}$ and $\\epsilon^b \\in \\mathbb{R}^q$ are noise random variables which can be generated by one of the following two ways:\n",
    "\n",
    "1. **Independent Gaussian noise**: the noise applied to each weight and bias is independent, where each random noise entry is drawn from a unit Gaussian distribution. This means that for each noisy linear layer, there are $pq + q$ noise variables (for $p$ inputs to the layer and $q$ outputs).\n",
    "2. **Factorised Gaussian noise:** This is a more computationally efficient way. It produces 2 random Gaussian noise vectors ($p, q$) and makes $pq + q$ noise entries by outer product as follows:\n",
    "\n",
    "$$\n",
    "\\begin{align}\n",
    "\\epsilon_{i,j}^w &= f(\\epsilon_i) f(\\epsilon_j),\\\\\n",
    "\\epsilon_{j}^b &= f(\\epsilon_i),\\\\\n",
    "\\text{where } f(x) &= sgn(x) \\sqrt{|x|}.\n",
    "\\end{align}\n",
    "$$\n",
    "\n",
    "In all experiements of the paper, the authors used Factorised Gaussian noise, so we will go for it as well."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "import math\n",
    "import os\n",
    "from typing import Dict, List, Tuple\n",
    "\n",
    "import gym\n",
    "import matplotlib.pyplot as plt\n",
    "import numpy as np\n",
    "import torch\n",
    "import torch.nn as nn\n",
    "import torch.nn.functional as F\n",
    "import torch.optim as optim\n",
    "from IPython.display import clear_output"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Replay buffer\n",
    "\n",
    "Please see *01.dqn.ipynb* for detailed description."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "class ReplayBuffer:\n",
    "    \"\"\"A simple numpy replay buffer.\"\"\"\n",
    "\n",
    "    def __init__(self, obs_dim: int, size: int, batch_size: int = 32):\n",
    "        self.obs_buf = np.zeros([size, obs_dim], dtype=np.float32)\n",
    "        self.next_obs_buf = np.zeros([size, obs_dim], dtype=np.float32)\n",
    "        self.acts_buf = np.zeros([size], dtype=np.float32)\n",
    "        self.rews_buf = np.zeros([size], dtype=np.float32)\n",
    "        self.done_buf = np.zeros(size, dtype=np.float32)\n",
    "        self.max_size, self.batch_size = size, batch_size\n",
    "        self.ptr, self.size, = 0, 0\n",
    "\n",
    "    def store(\n",
    "        self,\n",
    "        obs: np.ndarray,\n",
    "        act: np.ndarray, \n",
    "        rew: float, \n",
    "        next_obs: np.ndarray, \n",
    "        done: bool,\n",
    "    ):\n",
    "        self.obs_buf[self.ptr] = obs\n",
    "        self.next_obs_buf[self.ptr] = next_obs\n",
    "        self.acts_buf[self.ptr] = act\n",
    "        self.rews_buf[self.ptr] = rew\n",
    "        self.done_buf[self.ptr] = done\n",
    "        self.ptr = (self.ptr + 1) % self.max_size\n",
    "        self.size = min(self.size + 1, self.max_size)\n",
    "\n",
    "    def sample_batch(self) -> Dict[str, np.ndarray]:\n",
    "        idxs = np.random.choice(self.size, size=self.batch_size, replace=False)\n",
    "        return dict(obs=self.obs_buf[idxs],\n",
    "                    next_obs=self.next_obs_buf[idxs],\n",
    "                    acts=self.acts_buf[idxs],\n",
    "                    rews=self.rews_buf[idxs],\n",
    "                    done=self.done_buf[idxs])\n",
    "\n",
    "    def __len__(self) -> int:\n",
    "        return self.size"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Noisy Layer\n",
    "\n",
    "**References:**\n",
    "- https://github.com/higgsfield/RL-Adventure/blob/master/5.noisy%20dqn.ipynb\n",
    "- https://github.com/Kaixhin/Rainbow/blob/master/model.py"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "class NoisyLinear(nn.Module):\n",
    "    \"\"\"Noisy linear module for NoisyNet.\n",
    "    \n",
    "    Attributes:\n",
    "        in_features (int): input size of linear module\n",
    "        out_features (int): output size of linear module\n",
    "        std_init (float): initial std value\n",
    "        weight_mu (nn.Parameter): mean value weight parameter\n",
    "        weight_sigma (nn.Parameter): std value weight parameter\n",
    "        bias_mu (nn.Parameter): mean value bias parameter\n",
    "        bias_sigma (nn.Parameter): std value bias parameter\n",
    "        \n",
    "    \"\"\"\n",
    "\n",
    "    def __init__(self, in_features: int, out_features: int, std_init: float = 0.5):\n",
    "        \"\"\"Initialization.\"\"\"\n",
    "        super(NoisyLinear, self).__init__()\n",
    "        \n",
    "        self.in_features = in_features\n",
    "        self.out_features = out_features\n",
    "        self.std_init = std_init\n",
    "\n",
    "        self.weight_mu = nn.Parameter(torch.Tensor(out_features, in_features))\n",
    "        self.weight_sigma = nn.Parameter(\n",
    "            torch.Tensor(out_features, in_features)\n",
    "        )\n",
    "        self.register_buffer(\n",
    "            \"weight_epsilon\", torch.Tensor(out_features, in_features)\n",
    "        )\n",
    "\n",
    "        self.bias_mu = nn.Parameter(torch.Tensor(out_features))\n",
    "        self.bias_sigma = nn.Parameter(torch.Tensor(out_features))\n",
    "        self.register_buffer(\"bias_epsilon\", torch.Tensor(out_features))\n",
    "\n",
    "        self.reset_parameters()\n",
    "        self.reset_noise()\n",
    "\n",
    "    def reset_parameters(self):\n",
    "        \"\"\"Reset trainable network parameters (factorized gaussian noise).\"\"\"\n",
    "        mu_range = 1 / math.sqrt(self.in_features)\n",
    "        self.weight_mu.data.uniform_(-mu_range, mu_range)\n",
    "        self.weight_sigma.data.fill_(\n",
    "            self.std_init / math.sqrt(self.in_features)\n",
    "        )\n",
    "        self.bias_mu.data.uniform_(-mu_range, mu_range)\n",
    "        self.bias_sigma.data.fill_(\n",
    "            self.std_init / math.sqrt(self.out_features)\n",
    "        )\n",
    "\n",
    "    def reset_noise(self):\n",
    "        \"\"\"Make new noise.\"\"\"\n",
    "        epsilon_in = self.scale_noise(self.in_features)\n",
    "        epsilon_out = self.scale_noise(self.out_features)\n",
    "\n",
    "        # outer product\n",
    "        self.weight_epsilon.copy_(epsilon_out.ger(epsilon_in))\n",
    "        self.bias_epsilon.copy_(epsilon_out)\n",
    "\n",
    "    def forward(self, x: torch.Tensor) -> torch.Tensor:\n",
    "        \"\"\"Forward method implementation.\n",
    "        \n",
    "        We don't use separate statements on train / eval mode.\n",
    "        It doesn't show remarkable difference of performance.\n",
    "        \"\"\"\n",
    "        return F.linear(\n",
    "            x,\n",
    "            self.weight_mu + self.weight_sigma * self.weight_epsilon,\n",
    "            self.bias_mu + self.bias_sigma * self.bias_epsilon,\n",
    "        )\n",
    "    \n",
    "    @staticmethod\n",
    "    def scale_noise(size: int) -> torch.Tensor:\n",
    "        \"\"\"Set scale to make noise (factorized gaussian noise).\"\"\"\n",
    "        x = torch.FloatTensor(np.random.normal(loc=0.0, scale=1.0, size=size))\n",
    "\n",
    "        return x.sign().mul(x.abs().sqrt())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Noisy Network\n",
    "\n",
    "We use NoisyLinear for the last two FC layers, and there is a method to reset noise at every step.\n",
    "These are the only differences from the example of *01.dqn.ipynb*."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "class Network(nn.Module):\n",
    "    def __init__(self, in_dim: int, out_dim: int):\n",
    "        \"\"\"Initialization.\"\"\"\n",
    "        super(Network, self).__init__()\n",
    "\n",
    "        self.feature = nn.Linear(in_dim, 128)\n",
    "        self.noisy_layer1 = NoisyLinear(128, 128)\n",
    "        self.noisy_layer2 = NoisyLinear(128, out_dim)\n",
    "\n",
    "    def forward(self, x: torch.Tensor) -> torch.Tensor:\n",
    "        \"\"\"Forward method implementation.\"\"\"\n",
    "        feature = F.relu(self.feature(x))\n",
    "        hidden = F.relu(self.noisy_layer1(feature))\n",
    "        out = self.noisy_layer2(hidden)\n",
    "        \n",
    "        return out\n",
    "    \n",
    "    def reset_noise(self):\n",
    "        \"\"\"Reset all noisy layers.\"\"\"\n",
    "        self.noisy_layer1.reset_noise()\n",
    "        self.noisy_layer2.reset_noise()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## DQN + NoisyNet Agent (w/o DuelingNet)\n",
    "\n",
    "Here is a summary of DQNAgent class.\n",
    "\n",
    "| Method           | Note                                                 |\n",
    "| ---              | ---                                                  |\n",
    "|select_action     | select an action from the input state.               |\n",
    "|step              | take an action and return the response of the env.   |\n",
    "|compute_dqn_loss  | return dqn loss.                                     |\n",
    "|update_model      | update the model by gradient descent.                |\n",
    "|target_hard_update| hard update from the local model to the target model.|\n",
    "|train             | train the agent during num_frames.                   |\n",
    "|test              | test the agent (1 episode).                          |\n",
    "|plot              | plot the training progresses.                        |\n",
    "\n",
    "In the paper, NoisyNet is used as a component of the Dueling Network Architecture, which includes Double-DQN and Prioritized Experience Replay. However, we don't implement them to simplify the tutorial. One thing to note is that NoisyNet is an alternertive to $\\epsilon$-greedy method, so all $\\epsilon$ related lines are removed. Please check all comments with *NoisyNet*."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "class DQNAgent:\n",
    "    \"\"\"DQN Agent interacting with environment.\n",
    "    \n",
    "    Attribute:\n",
    "        env (gym.Env): openAI Gym environment\n",
    "        memory (ReplayBuffer): replay memory to store transitions\n",
    "        batch_size (int): batch size for sampling\n",
    "        target_update (int): period for target model's hard update\n",
    "        gamma (float): discount factor\n",
    "        dqn (Network): model to train and select actions\n",
    "        dqn_target (Network): target model to update\n",
    "        optimizer (torch.optim): optimizer for training dqn\n",
    "        transition (list): transition information including\n",
    "                           state, action, reward, next_state, done\n",
    "    \"\"\"\n",
    "\n",
    "    def __init__(\n",
    "        self, \n",
    "        env: gym.Env,\n",
    "        memory_size: int,\n",
    "        batch_size: int,\n",
    "        target_update: int,\n",
    "        gamma: float = 0.99,\n",
    "    ):\n",
    "        \"\"\"Initialization.\n",
    "        \n",
    "        Args:\n",
    "            env (gym.Env): openAI Gym environment\n",
    "            memory_size (int): length of memory\n",
    "            batch_size (int): batch size for sampling\n",
    "            target_update (int): period for target model's hard update\n",
    "            gamma (float): discount factor\n",
    "        \"\"\"\n",
    "        # NoisyNet: All attributes related to epsilon are removed\n",
    "        obs_dim = env.observation_space.shape[0]\n",
    "        action_dim = env.action_space.n\n",
    "        \n",
    "        self.env = env\n",
    "        self.memory = ReplayBuffer(obs_dim, memory_size, batch_size)\n",
    "        self.batch_size = batch_size\n",
    "        self.target_update = target_update\n",
    "        self.gamma = gamma\n",
    "        \n",
    "        # device: cpu / gpu\n",
    "        self.device = torch.device(\n",
    "            \"cuda\" if torch.cuda.is_available() else \"cpu\"\n",
    "        )\n",
    "        print(self.device)\n",
    "\n",
    "        # networks: dqn, dqn_target\n",
    "        self.dqn = Network(obs_dim, action_dim).to(self.device)\n",
    "        self.dqn_target = Network(obs_dim, action_dim).to(self.device)\n",
    "        self.dqn_target.load_state_dict(self.dqn.state_dict())\n",
    "        self.dqn_target.eval()\n",
    "        \n",
    "        # optimizer\n",
    "        self.optimizer = optim.Adam(self.dqn.parameters())\n",
    "\n",
    "        # transition to store in memory\n",
    "        self.transition = list()\n",
    "        \n",
    "        # mode: train / test\n",
    "        self.is_test = False\n",
    "\n",
    "    def select_action(self, state: np.ndarray) -> np.ndarray:\n",
    "        \"\"\"Select an action from the input state.\"\"\"\n",
    "        # NoisyNet: no epsilon greedy action selection\n",
    "        selected_action = self.dqn(\n",
    "            torch.FloatTensor(state).to(self.device)\n",
    "        ).argmax()\n",
    "        selected_action = selected_action.detach().cpu().numpy()\n",
    "        \n",
    "        if not self.is_test:\n",
    "            self.transition = [state, selected_action]\n",
    "        \n",
    "        return selected_action\n",
    "\n",
    "    def step(self, action: np.ndarray) -> Tuple[np.ndarray, np.float64, bool]:\n",
    "        \"\"\"Take an action and return the response of the env.\"\"\"\n",
    "        next_state, reward, done, _ = self.env.step(action)\n",
    "\n",
    "        if not self.is_test:\n",
    "            self.transition += [reward, next_state, done]\n",
    "            self.memory.store(*self.transition)\n",
    "    \n",
    "        return next_state, reward, done\n",
    "\n",
    "    def update_model(self) -> torch.Tensor:\n",
    "        \"\"\"Update the model by gradient descent.\"\"\"\n",
    "        samples = self.memory.sample_batch()\n",
    "\n",
    "        loss = self._compute_dqn_loss(samples)\n",
    "\n",
    "        self.optimizer.zero_grad()\n",
    "        loss.backward()\n",
    "        self.optimizer.step()\n",
    "        \n",
    "        # NoisyNet: reset noise\n",
    "        self.dqn.reset_noise()\n",
    "        self.dqn_target.reset_noise()\n",
    "\n",
    "        return loss.item()\n",
    "        \n",
    "    def train(self, num_frames: int, plotting_interval: int = 200):\n",
    "        \"\"\"Train the agent.\"\"\"\n",
    "        self.is_test = False\n",
    "        \n",
    "        state = self.env.reset()\n",
    "        update_cnt = 0\n",
    "        losses = []\n",
    "        scores = []\n",
    "        score = 0\n",
    "\n",
    "        for frame_idx in range(1, num_frames + 1):\n",
    "            action = self.select_action(state)\n",
    "            next_state, reward, done = self.step(action)\n",
    "\n",
    "            state = next_state\n",
    "            score += reward\n",
    "            \n",
    "            # NoisyNet: removed decrease of epsilon\n",
    "\n",
    "            # if episode ends\n",
    "            if done:\n",
    "                state = self.env.reset()\n",
    "                scores.append(score)\n",
    "                score = 0\n",
    "\n",
    "            # if training is ready\n",
    "            if len(self.memory) >= self.batch_size:\n",
    "                loss = self.update_model()\n",
    "                losses.append(loss)\n",
    "                update_cnt += 1\n",
    "                \n",
    "                # if hard update is needed\n",
    "                if update_cnt % self.target_update == 0:\n",
    "                    self._target_hard_update()\n",
    "\n",
    "            # plotting\n",
    "            if frame_idx % plotting_interval == 0:\n",
    "                self._plot(frame_idx, scores, losses)\n",
    "                \n",
    "        self.env.close()\n",
    "                \n",
    "    def test(self) -> List[np.ndarray]:\n",
    "        \"\"\"Test the agent.\"\"\"\n",
    "        self.is_test = True\n",
    "        \n",
    "        state = self.env.reset()\n",
    "        done = False\n",
    "        score = 0\n",
    "        \n",
    "        frames = []\n",
    "        while not done:\n",
    "            frames.append(self.env.render(mode=\"rgb_array\"))\n",
    "            action = self.select_action(state)\n",
    "            next_state, reward, done = self.step(action)\n",
    "\n",
    "            state = next_state\n",
    "            score += reward\n",
    "        \n",
    "        print(\"score: \", score)\n",
    "        self.env.close()\n",
    "        \n",
    "        return frames\n",
    "\n",
    "    def _compute_dqn_loss(self, samples: Dict[str, np.ndarray]) -> torch.Tensor:\n",
    "        \"\"\"Return dqn loss.\"\"\"\n",
    "        device = self.device  # for shortening the following lines\n",
    "        state = torch.FloatTensor(samples[\"obs\"]).to(device)\n",
    "        next_state = torch.FloatTensor(samples[\"next_obs\"]).to(device)\n",
    "        action = torch.LongTensor(samples[\"acts\"].reshape(-1, 1)).to(device)\n",
    "        reward = torch.FloatTensor(samples[\"rews\"].reshape(-1, 1)).to(device)\n",
    "        done = torch.FloatTensor(samples[\"done\"].reshape(-1, 1)).to(device)\n",
    "        \n",
    "        # G_t   = r + gamma * v(s_{t+1})  if state != Terminal\n",
    "        #       = r                       otherwise\n",
    "        curr_q_value = self.dqn(state).gather(1, action)\n",
    "        next_q_value = self.dqn_target(next_state).max(\n",
    "            dim=1, keepdim=True\n",
    "        )[0].detach()\n",
    "        mask = 1 - done\n",
    "        target = (reward + self.gamma * next_q_value * mask).to(self.device)\n",
    "\n",
    "        # calculate dqn loss\n",
    "        loss = F.smooth_l1_loss(curr_q_value, target)\n",
    "\n",
    "        return loss\n",
    "\n",
    "    def _target_hard_update(self):\n",
    "        \"\"\"Hard update: target <- local.\"\"\"\n",
    "        self.dqn_target.load_state_dict(self.dqn.state_dict())\n",
    "                \n",
    "    def _plot(\n",
    "        self, \n",
    "        frame_idx: int, \n",
    "        scores: List[float], \n",
    "        losses: List[float], \n",
    "    ):\n",
    "        \"\"\"Plot the training progresses.\"\"\"\n",
    "        clear_output(True)\n",
    "        plt.figure(figsize=(20, 5))\n",
    "        plt.subplot(131)\n",
    "        plt.title('frame %s. score: %s' % (frame_idx, np.mean(scores[-10:])))\n",
    "        plt.plot(scores)\n",
    "        plt.subplot(132)\n",
    "        plt.title('loss')\n",
    "        plt.plot(losses)\n",
    "        plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Environment\n",
    "\n",
    "You can see the [code](https://github.com/openai/gym/blob/master/gym/envs/classic_control/cartpole.py) and [configurations](https://github.com/openai/gym/blob/master/gym/envs/__init__.py#L53) of CartPole-v0 from OpenAI's repository."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "# environment\n",
    "env_id = \"CartPole-v0\"\n",
    "env = gym.make(env_id)\n",
    "if IN_COLAB:\n",
    "    env = gym.wrappers.Monitor(env, \"videos\", force=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Set random seed"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[777]"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "seed = 777\n",
    "\n",
    "def seed_torch(seed):\n",
    "    torch.manual_seed(seed)\n",
    "    if torch.backends.cudnn.enabled:\n",
    "        torch.backends.cudnn.benchmark = False\n",
    "        torch.backends.cudnn.deterministic = True\n",
    "\n",
    "np.random.seed(seed)\n",
    "seed_torch(seed)\n",
    "env.seed(seed)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Initialize"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "cpu\n"
     ]
    }
   ],
   "source": [
    "# parameters\n",
    "num_frames = 20000\n",
    "memory_size = 2000\n",
    "batch_size = 64\n",
    "target_update = 150\n",
    "\n",
    "# train\n",
    "agent = DQNAgent(env, memory_size, batch_size, target_update)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Train"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 1440x360 with 2 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "agent.train(num_frames)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Test\n",
    "\n",
    "Run the trained agent (1 episode)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "score:  200.0\n"
     ]
    }
   ],
   "source": [
    "frames = agent.test()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Render"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "\n",
       "<script language=\"javascript\">\n",
       "  /* Define the Animation class */\n",
       "  function Animation(frames, img_id, slider_id, interval, loop_select_id){\n",
       "    this.img_id = img_id;\n",
       "    this.slider_id = slider_id;\n",
       "    this.loop_select_id = loop_select_id;\n",
       "    this.interval = interval;\n",
       "    this.current_frame = 0;\n",
       "    this.direction = 0;\n",
       "    this.timer = null;\n",
       "    this.frames = new Array(frames.length);\n",
       "\n",
       "    for (var i=0; i<frames.length; i++)\n",
       "    {\n",
       "     this.frames[i] = new Image();\n",
       "     this.frames[i].src = frames[i];\n",
       "    }\n",
       "    document.getElementById(this.slider_id).max = this.frames.length - 1;\n",
       "    this.set_frame(this.current_frame);\n",
       "  }\n",
       "\n",
       "  Animation.prototype.get_loop_state = function(){\n",
       "    var button_group = document[this.loop_select_id].state;\n",
       "    for (var i = 0; i < button_group.length; i++) {\n",
       "        var button = button_group[i];\n",
       "        if (button.checked) {\n",
       "            return button.value;\n",
       "        }\n",
       "    }\n",
       "    return undefined;\n",
       "  }\n",
       "\n",
       "  Animation.prototype.set_frame = function(frame){\n",
       "    this.current_frame = frame;\n",
       "    document.getElementById(this.img_id).src = this.frames[this.current_frame].src;\n",
       "    document.getElementById(this.slider_id).value = this.current_frame;\n",
       "  }\n",
       "\n",
       "  Animation.prototype.next_frame = function()\n",
       "  {\n",
       "    this.set_frame(Math.min(this.frames.length - 1, this.current_frame + 1));\n",
       "  }\n",
       "\n",
       "  Animation.prototype.previous_frame = function()\n",
       "  {\n",
       "    this.set_frame(Math.max(0, this.current_frame - 1));\n",
       "  }\n",
       "\n",
       "  Animation.prototype.first_frame = function()\n",
       "  {\n",
       "    this.set_frame(0);\n",
       "  }\n",
       "\n",
       "  Animation.prototype.last_frame = function()\n",
       "  {\n",
       "    this.set_frame(this.frames.length - 1);\n",
       "  }\n",
       "\n",
       "  Animation.prototype.slower = function()\n",
       "  {\n",
       "    this.interval /= 0.7;\n",
       "    if(this.direction > 0){this.play_animation();}\n",
       "    else if(this.direction < 0){this.reverse_animation();}\n",
       "  }\n",
       "\n",
       "  Animation.prototype.faster = function()\n",
       "  {\n",
       "    this.interval *= 0.7;\n",
       "    if(this.direction > 0){this.play_animation();}\n",
       "    else if(this.direction < 0){this.reverse_animation();}\n",
       "  }\n",
       "\n",
       "  Animation.prototype.anim_step_forward = function()\n",
       "  {\n",
       "    this.current_frame += 1;\n",
       "    if(this.current_frame < this.frames.length){\n",
       "      this.set_frame(this.current_frame);\n",
       "    }else{\n",
       "      var loop_state = this.get_loop_state();\n",
       "      if(loop_state == \"loop\"){\n",
       "        this.first_frame();\n",
       "      }else if(loop_state == \"reflect\"){\n",
       "        this.last_frame();\n",
       "        this.reverse_animation();\n",
       "      }else{\n",
       "        this.pause_animation();\n",
       "        this.last_frame();\n",
       "      }\n",
       "    }\n",
       "  }\n",
       "\n",
       "  Animation.prototype.anim_step_reverse = function()\n",
       "  {\n",
       "    this.current_frame -= 1;\n",
       "    if(this.current_frame >= 0){\n",
       "      this.set_frame(this.current_frame);\n",
       "    }else{\n",
       "      var loop_state = this.get_loop_state();\n",
       "      if(loop_state == \"loop\"){\n",
       "        this.last_frame();\n",
       "      }else if(loop_state == \"reflect\"){\n",
       "        this.first_frame();\n",
       "        this.play_animation();\n",
       "      }else{\n",
       "        this.pause_animation();\n",
       "        this.first_frame();\n",
       "      }\n",
       "    }\n",
       "  }\n",
       "\n",
       "  Animation.prototype.pause_animation = function()\n",
       "  {\n",
       "    this.direction = 0;\n",
       "    if (this.timer){\n",
       "      clearInterval(this.timer);\n",
       "      this.timer = null;\n",
       "    }\n",
       "  }\n",
       "\n",
       "  Animation.prototype.play_animation = function()\n",
       "  {\n",
       "    this.pause_animation();\n",
       "    this.direction = 1;\n",
       "    var t = this;\n",
       "    if (!this.timer) this.timer = setInterval(function(){t.anim_step_forward();}, this.interval);\n",
       "  }\n",
       "\n",
       "  Animation.prototype.reverse_animation = function()\n",
       "  {\n",
       "    this.pause_animation();\n",
       "    this.direction = -1;\n",
       "    var t = this;\n",
       "    if (!this.timer) this.timer = setInterval(function(){t.anim_step_reverse();}, this.interval);\n",
       "  }\n",
       "</script>\n",
       "\n",
       "<div class=\"animation\" align=\"center\">\n",
       "    <img id=\"_anim_imgAIQGJIPYORMKTILJ\">\n",
       "    <br>\n",
       "    <input id=\"_anim_sliderAIQGJIPYORMKTILJ\" type=\"range\" style=\"width:350px\" name=\"points\" min=\"0\" max=\"1\" step=\"1\" value=\"0\" onchange=\"animAIQGJIPYORMKTILJ.set_frame(parseInt(this.value));\"></input>\n",
       "    <br>\n",
       "    <button onclick=\"animAIQGJIPYORMKTILJ.slower()\">&#8211;</button>\n",
       "    <button onclick=\"animAIQGJIPYORMKTILJ.first_frame()\"><img class=\"anim_icon\" src=\"\"></button>\n",
       "    <button onclick=\"animAIQGJIPYORMKTILJ.previous_frame()\"><img class=\"anim_icon\" src=\"\"></button>\n",
       "    <button onclick=\"animAIQGJIPYORMKTILJ.reverse_animation()\"><img class=\"anim_icon\" src=\"\"></button>\n",
       "    <button onclick=\"animAIQGJIPYORMKTILJ.pause_animation()\"><img class=\"anim_icon\" src=\"\"></button>\n",
       "    <button onclick=\"animAIQGJIPYORMKTILJ.play_animation()\"><img class=\"anim_icon\" src=\"\"></button>\n",
       "    <button onclick=\"animAIQGJIPYORMKTILJ.next_frame()\"><img class=\"anim_icon\" src=\"\"></button>\n",
       "    <button onclick=\"animAIQGJIPYORMKTILJ.last_frame()\"><img class=\"anim_icon\" src=\"\"></button>\n",
       "    <button onclick=\"animAIQGJIPYORMKTILJ.faster()\">+</button>\n",
       "  <form action=\"#n\" name=\"_anim_loop_selectAIQGJIPYORMKTILJ\" class=\"anim_control\">\n",
       "    <input type=\"radio\" name=\"state\" value=\"once\" > Once </input>\n",
       "    <input type=\"radio\" name=\"state\" value=\"loop\" checked> Loop </input>\n",
       "    <input type=\"radio\" name=\"state\" value=\"reflect\" > Reflect </input>\n",
       "  </form>\n",
       "</div>\n",
       "\n",
       "\n",
       "<script language=\"javascript\">\n",
       "  /* Instantiate the Animation class. */\n",
       "  /* The IDs given should match those used in the template above. */\n",
       "  (function() {\n",
       "    var img_id = \"_anim_imgAIQGJIPYORMKTILJ\";\n",
       "    var slider_id = \"_anim_sliderAIQGJIPYORMKTILJ\";\n",
       "    var loop_select_id = \"_anim_loop_selectAIQGJIPYORMKTILJ\";\n",
       "    var frames = new Array(0);\n",
       "    \n",
       "  frames[0] = \"\"\n",
       "  frames[1] = \"\"\n",
       "  frames[2] = \"\"\n",
       "  frames[3] = \"\"\n",
       "  frames[4] = \"\"\n",
       "  frames[5] = \"\"\n",
       "  frames[6] = \"\"\n",
       "  frames[7] = \"\"\n",
       "  frames[8] = \"\"\n",
       "  frames[9] = \"\"\n",
       "  frames[10] = \"\"\n",
       "  frames[11] = \"\"\n",
       "  frames[12] = \"\"\n",
       "  frames[13] = \"\"\n",
       "  frames[14] = \"\"\n",
       "  frames[15] = \"\"\n",
       "  frames[16] = \"\"\n",
       "  frames[17] = \"\"\n",
       "  frames[18] = \"\"\n",
       "  frames[19] = \"\"\n",
       "  frames[20] = \"\"\n",
       "  frames[21] = \"\"\n",
       "  frames[22] = \"\"\n",
       "  frames[23] = \"\"\n",
       "  frames[24] = \"\"\n",
       "  frames[25] = \"\"\n",
       "  frames[26] = \"\"\n",
       "  frames[27] = \"\"\n",
       "  frames[28] = \"\"\n",
       "  frames[29] = \"\"\n",
       "  frames[30] = \"\"\n",
       "  frames[31] = \"\"\n",
       "  frames[32] = \"\"\n",
       "  frames[33] = \"\"\n",
       "  frames[34] = \"\"\n",
       "  frames[35] = \"\"\n",
       "  frames[36] = \"\"\n",
       "  frames[37] = \"\"\n",
       "  frames[38] = \"\"\n",
       "  frames[39] = \"\"\n",
       "  frames[40] = \"\"\n",
       "  frames[41] = \"\"\n",
       "  frames[42] = \"\"\n",
       "  frames[43] = \"\"\n",
       "  frames[44] = \"\"\n",
       "  frames[45] = \"\"\n",
       "  frames[46] = \"\"\n",
       "  frames[47] = \"\"\n",
       "  frames[48] = \"\"\n",
       "  frames[49] = \"\"\n",
       "  frames[50] = \"\"\n",
       "  frames[51] = \"\"\n",
       "  frames[52] = \"\"\n",
       "  frames[53] = \"\"\n",
       "  frames[54] = \"\"\n",
       "  frames[55] = \"\"\n",
       "  frames[56] = \"\"\n",
       "  frames[57] = \"\"\n",
       "  frames[58] = \"\"\n",
       "  frames[59] = \"\"\n",
       "  frames[60] = \"\"\n",
       "  frames[61] = \"\"\n",
       "  frames[62] = \"\"\n",
       "  frames[63] = \"\"\n",
       "  frames[64] = \"\"\n",
       "  frames[65] = \"\"\n",
       "  frames[66] = \"\"\n",
       "  frames[67] = \"\"\n",
       "  frames[68] = \"\"\n",
       "  frames[69] = \"\"\n",
       "  frames[70] = \"\"\n",
       "  frames[71] = \"\"\n",
       "  frames[72] = \"\"\n",
       "  frames[73] = \"\"\n",
       "  frames[74] = \"\"\n",
       "  frames[75] = \"\"\n",
       "  frames[76] = \"\"\n",
       "  frames[77] = \"\"\n",
       "  frames[78] = \"\"\n",
       "  frames[79] = \"\"\n",
       "  frames[80] = \"\"\n",
       "  frames[81] = \"\"\n",
       "  frames[82] = \"\"\n",
       "  frames[83] = \"\"\n",
       "  frames[84] = \"\"\n",
       "  frames[85] = \"\"\n",
       "  frames[86] = \"\"\n",
       "  frames[87] = \"\"\n",
       "  frames[88] = \"\"\n",
       "  frames[89] = \"\"\n",
       "  frames[90] = \"\"\n",
       "  frames[91] = \"\"\n",
       "  frames[92] = \"\"\n",
       "  frames[93] = \"\"\n",
       "  frames[94] = \"\"\n",
       "  frames[95] = \"\"\n",
       "  frames[96] = \"\"\n",
       "  frames[97] = \"\"\n",
       "  frames[98] = \"\"\n",
       "  frames[99] = \"\"\n",
       "  frames[100] = \"\"\n",
       "  frames[101] = \"\"\n",
       "  frames[102] = \"\"\n",
       "  frames[103] = \"\"\n",
       "  frames[104] = \"\"\n",
       "  frames[105] = \"\"\n",
       "  frames[106] = \"\"\n",
       "  frames[107] = \"\"\n",
       "  frames[108] = \"\"\n",
       "  frames[109] = \"\"\n",
       "  frames[110] = \"\"\n",
       "  frames[111] = \"\"\n",
       "  frames[112] = \"\"\n",
       "  frames[113] = \"\"\n",
       "  frames[114] = \"\"\n",
       "  frames[115] = \"\"\n",
       "  frames[116] = \"\"\n",
       "  frames[117] = \"\"\n",
       "  frames[118] = \"\"\n",
       "  frames[119] = \"\"\n",
       "  frames[120] = \"\"\n",
       "  frames[121] = \"\"\n",
       "  frames[122] = \"\"\n",
       "  frames[123] = \"\"\n",
       "  frames[124] = \"\"\n",
       "  frames[125] = \"\"\n",
       "  frames[126] = \"\"\n",
       "  frames[127] = \"\"\n",
       "  frames[128] = \"\"\n",
       "  frames[129] = \"\"\n",
       "  frames[130] = \"\"\n",
       "  frames[131] = \"\"\n",
       "  frames[132] = \"\"\n",
       "  frames[133] = \"\"\n",
       "  frames[134] = \"\"\n",
       "  frames[135] = \"\"\n",
       "  frames[136] = \"\"\n",
       "  frames[137] = \"\"\n",
       "  frames[138] = \"\"\n",
       "  frames[139] = \"\"\n",
       "  frames[140] = \"\"\n",
       "  frames[141] = \"\"\n",
       "  frames[142] = \"\"\n",
       "  frames[143] = \"\"\n",
       "  frames[144] = \"\"\n",
       "  frames[145] = \"\"\n",
       "  frames[146] = \"\"\n",
       "  frames[147] = \"\"\n",
       "  frames[148] = \"\"\n",
       "  frames[149] = \"\"\n",
       "  frames[150] = \"\"\n",
       "  frames[151] = \"\"\n",
       "  frames[152] = \"\"\n",
       "  frames[153] = \"\"\n",
       "  frames[154] = \"\"\n",
       "  frames[155] = \"\"\n",
       "  frames[156] = \"\"\n",
       "  frames[157] = \"\"\n",
       "  frames[158] = \"\"\n",
       "  frames[159] = \"\"\n",
       "  frames[160] = \"\"\n",
       "  frames[161] = \"\"\n",
       "  frames[162] = \"\"\n",
       "  frames[163] = \"\"\n",
       "  frames[164] = \"\"\n",
       "  frames[165] = \"\"\n",
       "  frames[166] = \"\"\n",
       "  frames[167] = \"\"\n",
       "  frames[168] = \"\"\n",
       "  frames[169] = \"\"\n",
       "  frames[170] = \"\"\n",
       "  frames[171] = \"\"\n",
       "  frames[172] = \"\"\n",
       "  frames[173] = \"\"\n",
       "  frames[174] = \"\"\n",
       "  frames[175] = \"\"\n",
       "  frames[176] = \"\"\n",
       "  frames[177] = \"\"\n",
       "  frames[178] = \"\"\n",
       "  frames[179] = \"\"\n",
       "  frames[180] = \"\"\n",
       "  frames[181] = \"\"\n",
       "  frames[182] = \"\"\n",
       "  frames[183] = \"\"\n",
       "  frames[184] = \"\"\n",
       "  frames[185] = \"\"\n",
       "  frames[186] = \"\"\n",
       "  frames[187] = \"\"\n",
       "  frames[188] = \"\"\n",
       "  frames[189] = \"\"\n",
       "  frames[190] = \"\"\n",
       "  frames[191] = \"\"\n",
       "  frames[192] = \"\"\n",
       "  frames[193] = \"\"\n",
       "  frames[194] = \"\"\n",
       "  frames[195] = \"\"\n",
       "  frames[196] = \"\"\n",
       "  frames[197] = \"\"\n",
       "  frames[198] = \"\"\n",
       "  frames[199] = \"\"\n",
       "\n",
       "\n",
       "    /* set a timeout to make sure all the above elements are created before\n",
       "       the object is initialized. */\n",
       "    setTimeout(function() {\n",
       "        animAIQGJIPYORMKTILJ = new Animation(frames, img_id, slider_id, 50, loop_select_id);\n",
       "    }, 0);\n",
       "  })()\n",
       "</script>\n"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "if IN_COLAB:  # for colab\n",
    "    import base64\n",
    "    import glob\n",
    "    import io\n",
    "    import os\n",
    "\n",
    "    from IPython.display import HTML, display\n",
    "\n",
    "\n",
    "    def ipython_show_video(path: str) -> None:\n",
    "        \"\"\"Show a video at `path` within IPython Notebook.\"\"\"\n",
    "        if not os.path.isfile(path):\n",
    "            raise NameError(\"Cannot access: {}\".format(path))\n",
    "\n",
    "        video = io.open(path, \"r+b\").read()\n",
    "        encoded = base64.b64encode(video)\n",
    "\n",
    "        display(HTML(\n",
    "            data=\"\"\"\n",
    "            <video alt=\"test\" controls>\n",
    "            <source src=\"data:video/mp4;base64,{0}\" type=\"video/mp4\"/>\n",
    "            </video>\n",
    "            \"\"\".format(encoded.decode(\"ascii\"))\n",
    "        ))\n",
    "\n",
    "    list_of_files = glob.glob(\"videos/*.mp4\")\n",
    "    latest_file = max(list_of_files, key=os.path.getctime)\n",
    "    print(latest_file)\n",
    "    ipython_show_video(latest_file)\n",
    "    \n",
    "else:  # for jupyter\n",
    "    from matplotlib import animation\n",
    "    from JSAnimation.IPython_display import display_animation\n",
    "    from IPython.display import display\n",
    "\n",
    "\n",
    "    def display_frames_as_gif(frames: List[np.ndarray]) -> None:\n",
    "        \"\"\"Displays a list of frames as a gif, with controls.\"\"\"\n",
    "        patch = plt.imshow(frames[0])\n",
    "        plt.axis('off')\n",
    "\n",
    "        def animate(i):\n",
    "            patch.set_data(frames[i])\n",
    "\n",
    "        anim = animation.FuncAnimation(\n",
    "            plt.gcf(), animate, frames = len(frames), interval=50\n",
    "        )\n",
    "        display(display_animation(anim, default_mode='loop'))\n",
    "\n",
    "\n",
    "    # display \n",
    "    display_frames_as_gif(frames)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
